import json
import traceback

from handler.ws_handler.digit_twin_handler import DigitTwinHandler
from handler.ws_handler.produce_manage_handler import PMHandler
from logger_config import logger
from services.sql_service.alarm_service import AlarmService
from services.sql_service.mes_service import MesService
from services.sql_service.plc_service import PLCService
from services.sql_service.production_service import ProductionService
from services.sql_service.station_service import StationService


class WsSchedulerTask(object):
    def __init__(self):
        self.pm = PMHandler
        self.dt = DigitTwinHandler
        self.mes_service: MesService = MesService()
        self.production_service: ProductionService = ProductionService()
        self.station_service: StationService = StationService()
        self.alarm_service: AlarmService = AlarmService()
        self.plc_service: PLCService = PLCService()

    @classmethod
    async def pack_message_and_send(cls, handler, key, data):
        try:
            data = {
                'key': key,
                'data': data
            }
            await handler.write_message(json.dumps(data, ensure_ascii=False))
            logger.info(f'sent key {key} to handler {handler} success,data:{data}')
        except Exception as e:
            logger.error(f"send key {key} to handler {handler} fail：{traceback.format_exc()}")
        return data

    async def send_bom(self):
        key = 'bom'
        for handler in self.pm.client_set:
            data = await self.mes_service.get_issue_order()
            await self.pack_message_and_send(handler, key, data)

    async def send_cur_day_issued_data(self):
        key = 'cur_day_issued_data'
        for handler in self.pm.client_set:
            data = await self.mes_service.cur_day_issued_data()
            await self.pack_message_and_send(handler, key, data)

    async def send_ten_day_data(self):
        key = 'ten_day_data'
        for handler in self.pm.client_set:
            data = await self.mes_service.get_ten_day_data()
            await self.pack_message_and_send(handler, key, data)

    async def send_pass_rate(self):
        key = 'pass_rate'
        for handler in self.pm.client_set:
            data = await self.production_service.get_pass_rate()
            await self.pack_message_and_send(handler, key, data)

    async def send_semi_finished_check_result(self):
        key1 = 'semi_finished_check_result'
        key2 = 'finished_check_result'
        for handler in self.dt.client_set:
            semi_finished_check_result, finished_check_result = await self.station_service.get_check_result()
            await self.pack_message_and_send(handler, key1, semi_finished_check_result)
            await self.pack_message_and_send(handler, key2, finished_check_result)

    async def send_quality_monitor(self):
        key = 'quality_monitor'
        for handler in self.dt.client_set:
            data = await self.production_service.cur_day_quality_monitor()
            await self.pack_message_and_send(handler, key, data)

    async def send_total_quality_monitor(self):
        key = 'total_quality_monitor'
        for handler in self.dt.client_set:
            data = await self.production_service.get_ten_10_total_quality()
            await self.pack_message_and_send(handler, key, data)

    async def send_day_product_trend(self):
        key = 'day_product_trend'
        for handler in self.dt.client_set:
            data = await self.production_service.day_product_trend()
            await self.pack_message_and_send(handler, key, data)

    async def send_alarm_data(self):
        key = 'alarm_data'
        for handler in self.dt.client_set:
            data = await self.alarm_service.alarm_data()
            await self.pack_message_and_send(handler, key, data)

    async def send_digit_twin_unit(self):
        key = 'digit_twin_unit'
        # 8个func对应8个机器人信息
        methods: list = self.plc_service.methods
        for handler in self.dt.client_set:
            # 根据某字段判断是推送哪个机器人的数据
            cur_method_index = handler.cur_method_index
            data = await methods[cur_method_index](self.plc_service)
            await self.pack_message_and_send(handler, key, data)
            handler.cur_method_index = (cur_method_index + 1) % len(methods)

    async def send_digit_status(self):
        key = 'digit_status'
        for handler in self.dt.client_set:
            datas: list = await self.plc_service.get_cur_robot_data()
            for d in datas:
                await self.pack_message_and_send(handler, key, d)
